package com.ruoyi.biz.service;

import java.lang.reflect.Field;
import java.util.*;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.biz.domain.BizProject;
import com.ruoyi.biz.mapper.BizProjectMapper;
import com.ruoyi.biz.model.excel.BizSectorExcel;
import com.ruoyi.biz.model.excel.OldBizSectorExcel;
import com.ruoyi.biz.model.resp.BizSectorResp;
import com.ruoyi.biz.model.resp.ExportResp;
import com.ruoyi.common.core.domain.DbArray;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;

import java.util.stream.Collectors;

import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.web.convert.SectorConvert;
import com.ruoyi.web.model.RuleModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.biz.mapper.BizSectorMapper;
import com.ruoyi.biz.domain.BizSector;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;


/**
 * 项目板块管理Service业务层处理
 *
 * @author ruoyi
 * @date 2024-12-19
 */
@Service
public class BizSectorService extends ServiceImpl<BizSectorMapper, BizSector> {
    @Autowired
    private BizProjectMapper bizProjectMapper;

    public void setDg() {
        List<BizSector> list = this.list();
        List<Long> ids = Arrays.asList(169L, 220L, 223L);
        List<BizSector> parentList = list.stream().filter(r -> ids.contains(r.getId())).collect(Collectors.toList());
        List<BizSector> childList = list.stream().filter(r -> r.getParentId() != 0).collect(Collectors.toList());
        for (BizSector parent : parentList) {
            List<BizSector> result = child(parent.getId(), childList);
            parent.setDg(1);
            result.forEach(r -> r.setDg(1));
            saveOrUpdate(parent);
            saveOrUpdateBatch(result);
        }
    }

    public List<BizSector> child(Long parentId, List<BizSector> all) {
        List<BizSector> result = new ArrayList<>();
        List<BizSector> childList = all.stream().filter(r -> Objects.equals(r.getParentId(), parentId)).collect(Collectors.toList());
        for (BizSector parent : childList) {
            result.addAll(child(parent.getId(), all));
        }
        result.addAll(childList);
        return result;
    }

    public BizSector findByName(String name, Long parentId) {
        LambdaQueryWrapper<BizSector> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.and(i -> i.eq(BizSector::getName, name));
        if (parentId != null) {
            queryWrapper.and(i -> i.eq(BizSector::getParentId, parentId));
        }
        List<BizSector> list = this.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return list.get(0);
    }

    public BizSector findByCode(String code) {
        LambdaQueryWrapper<BizSector> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.and(i -> i.eq(BizSector::getCode, code));
        List<BizSector> list = this.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return list.get(0);
    }

    public List<BizSector> listDg() {
        LambdaQueryWrapper<BizSector> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.and(i -> i.eq(BizSector::getDg, 1));
        return this.list(queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    public String importExcelFc(MultipartFile file) {
        List<BizSectorExcel> list = new ArrayList<>();
        try {
            list = EasyExcel.read(file.getInputStream()).head(BizSectorExcel.class).sheet().doReadSync();
        } catch (Exception e) {
            throw new ServiceException("EXCEL解析失败！");
        }
        if (CollectionUtils.isEmpty(list)) {
            throw new ServiceException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder failureMsg = new StringBuilder();

        for (int i = 0; i < list.size(); i++) {
            try {
                BizSectorExcel excel = list.get(i);
                BizSector current = null;
                if (StringUtils.isNotBlank(excel.getName1())) {
                    BizSector parent1 = findByName(excel.getName1(), null);
                    if (parent1 == null) {
                        parent1 = new BizSector();
                        parent1.setOrderNum(i + 1);
                        parent1.setName(excel.getName1());
                        parent1.setCode(UUID.randomUUID().toString().replace("-", ""));
                        parent1.setParentId(0L);
                        saveOrUpdate(parent1);
                    }
                    if (StringUtils.isNotBlank(excel.getName2())) {
                        BizSector parent2 = findByName(excel.getName2(), parent1.getId());
                        if (parent2 == null) {
                            parent2 = new BizSector();
                            parent2.setOrderNum(i + 1);
                            parent2.setName(excel.getName2());
                            parent2.setCode(UUID.randomUUID().toString().replace("-", ""));
                            parent2.setParentId(parent1.getId());
                            saveOrUpdate(parent2);
                        }
                        if (StringUtils.isNotBlank(excel.getName3())) {
                            BizSector parent3 = findByName(excel.getName3(), parent2.getId());
                            if (parent3 == null) {
                                parent3 = new BizSector();
                                parent3.setOrderNum(i + 1);
                                parent3.setName(excel.getName3());
                                parent3.setCode(UUID.randomUUID().toString().replace("-", ""));
                                parent3.setParentId(parent2.getId());
                                saveOrUpdate(parent3);
                            }
                            if (StringUtils.isNotBlank(excel.getName4())) {
                                BizSector parent4 = findByName(excel.getName4(), parent3.getId());
                                if (parent4 == null) {
                                    parent4 = new BizSector();
                                    parent4.setOrderNum(i + 1);
                                    parent4.setName(excel.getName4());
                                    parent4.setCode(UUID.randomUUID().toString().replace("-", ""));
                                    parent4.setParentId(parent3.getId());
                                    saveOrUpdate(parent4);
                                }
                                current = parent4;
                            } else {
                                current = parent3;
                            }
                        } else {
                            current = parent2;
                        }
                    } else {
                        current = parent1;
                    }
                }
                if (current == null) {
                    log.error("未匹配到！！！！！");
                    continue;
                }
                // 存储字段名的列表
                List<String> shows = new ArrayList<>();
                List<String> requireds = new ArrayList<>();
                JSONObject map = new JSONObject();
                // 通过反射获取字段
                Field[] fields = BizSectorExcel.class.getDeclaredFields();
                for (Field field : fields) {
                    if (field.getName().equals("name1")
                            || field.getName().equals("name2")
                            || field.getName().equals("name3")
                            || field.getName().equals("name4")
                    ) {
                        continue;
                    }
                    try {
                        // 暴力访问私有字段
                        field.setAccessible(true);
                        String value = (String) field.get(excel); // 获取字段值
                        ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
                        if (excelProperty == null) {
                            continue;
                        }
                        if (StringUtils.isNotBlank(value)) {
                            shows.add(field.getName());
                            if (value.equals("1")) {
                                requireds.add(field.getName());
                                map.put(field.getName(), Arrays.asList(new RuleModel(excelProperty.value()[1])));
                            }
                        }
                    } catch (IllegalAccessException e) {
                        log.error("处理选项出错！！！", e);
                    }
                }
                current.setFields(new DbArray(shows));
                current.setRequireds(new DbArray(requireds));
                current.setRequiredInfo(map);
                updateById(current);
                successNum++;
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、" + "第" + (i + 1) + "行导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            return "恭喜您，数据已全部导入成功！共 " + successNum + " 条。";
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public String importExcel(MultipartFile file) {
        List<OldBizSectorExcel> list = new ArrayList<>();
        try {
            list = EasyExcel.read(file.getInputStream()).head(OldBizSectorExcel.class).sheet().doReadSync();
        } catch (Exception e) {
            throw new ServiceException("EXCEL解析失败！");
        }
        if (CollectionUtils.isEmpty(list)) {
            throw new ServiceException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder failureMsg = new StringBuilder();

        for (int i = 0; i < list.size(); i++) {
            try {
                OldBizSectorExcel excel = list.get(i);
                if (StringUtils.isBlank(excel.getName())) {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、" + "第" + (i + 1) + "行板块名称不能为空！");
                    continue;
                }
                if (StringUtils.isBlank(excel.getCode())) {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、" + "第" + (i + 1) + "行板块代号不能为空！");
                    continue;
                }
                BizSector bizSector = SectorConvert.INSTANCE.toEntity(excel);
                BizSector old = baseMapper.getByCode(bizSector.getCode());
                if (old != null) {
                    throw new ServiceException("存在相同代号");
                }
                bizSector.setOrderNum(i + 1);
                if (StringUtils.isNotBlank(excel.getParentCode())) {
                    BizSector parent = baseMapper.getByCode(excel.getParentCode());
                    if (parent == null) {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + "、" + "第" + (i + 1) + "上级不存在！");
                    } else {
                        bizSector.setParentId(parent.getId());
                    }
                }
                saveOrUpdate(bizSector);
                successNum++;
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、" + "第" + (i + 1) + "行导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            return "恭喜您，数据已全部导入成功！共 " + successNum + " 条。";
        }
    }

    /**
     * 分页查询项目板块管理
     */
    public IPage<BizSectorResp> listPage(BizSector req) {
        return baseMapper.list(PageUtils.page(), req);
    }

    /**
     * 查询项目板块管理列表
     */
    public List<BizSectorResp> list(BizSector req) {
        return baseMapper.list(req);
    }

    public List<ExportResp> export() {
        List<ExportResp> list = baseMapper.export();
        for(ExportResp resp:list){
            String[] strs = resp.getFullPath().split("-");
            if(strs.length>=1) {
                resp.setT1(strs[0].replace(" ",""));
            }
            if(strs.length>=2) {
                resp.setT2(strs[1].replace(" ",""));
            }
            if(strs.length>=3) {
                resp.setT3(strs[2].replace(" ",""));
            }
            if(strs.length>=4) {
                resp.setT4(strs[3].replace(" ",""));
            }
        }
        return list;
    }

    /**
     * 根据ID查询
     */
    public BizSector selectById(Long id) {
        return baseMapper.selectById(id);
    }

    /**
     * 新增修改项目板块管理
     */
    @Transactional(rollbackFor = Exception.class)
    public void beforeSave(BizSector bizSector) {
        BizSector old = baseMapper.getByCode(bizSector.getCode());
        if (bizSector.getId() != null) {
            if (old != null && !old.getId().equals(bizSector.getId())) {
                throw new ServiceException("存在相同代号");
            }
            bizSector.setUpdateTime(DateUtils.getNowDate());
        } else {
            if (old != null) {
                throw new ServiceException("存在相同代号");
            }
            bizSector.setCreateTime(DateUtils.getNowDate());
            bizSector.setUpdateTime(DateUtils.getNowDate());
        }
        saveOrUpdate(bizSector);
    }

    /**
     * 批量删除项目板块管理
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteByIds(Long[] ids) {
        for (Long id : ids) {
            LambdaQueryWrapper<BizProject> wrapper = new LambdaQueryWrapper<>();
            wrapper.and(i -> i.eq(BizProject::getSectorId, id));
            List<BizProject> projectList = bizProjectMapper.selectList(wrapper);
            if (!CollectionUtils.isEmpty(projectList)) {
                BizSector model = selectById(id);
                List<String> pName = projectList.stream().map(BizProject::getProjectName).collect(Collectors.toList());
                throw new ServiceException(model.getName() + "被项目[" + String.join(",", pName) + "]使用，不允许删除！");
            }
        }
        return baseMapper.deleteBatchIds(Arrays.asList(ids));
    }

}
